package org.lds.message.center.common;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.lds.message.center.common.enums.ErrorEnum;
import org.lds.message.center.common.exception.BusinessException;
import org.lds.message.center.common.model.request.CommonRequest;
import org.lds.message.center.common.util.JsonUtil;
import org.lds.message.center.common.util.RestUtil;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@RequiredArgsConstructor
public abstract class AbstractMessageService<T extends CommonRequest> implements MessageService<T> {
    private final MessageHandler<T> messageHandler;

    /**
     * send之前先校验
     * @param request
     */
    public abstract void check(T request);


    @Override
    public void send(T request) {
        store(request);
    }
    protected abstract void store(T request);


    public void handle(T request) {
        sendAndCallback(request);
    }

    private void sendAndCallback(T request) {
        try {
            messageHandler.handle(request);
            callback(request, "200", null);
        } catch (Exception e) {
            log.error("doSend error.", e);
            callback(request, "500",
                    e instanceof BusinessException ? e.getMessage() : ErrorEnum.SYSTEM_ERROR.getErrMsg());
        }
    }

    private void callback(T request, String code, String message) {
        String callbackUrl = request.getCallbackUrl();
        if (StringUtils.isEmpty(callbackUrl)) return;

        String[] splitCallbackUrl = callbackUrl.split("\\?");
        if (ArrayUtils.isEmpty(splitCallbackUrl)) return;

        String callbackUri = splitCallbackUrl[0];

        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("code", code);
        if (StringUtils.isNotEmpty(message)) {
            paramMap.put("message", message);
        }
        if (splitCallbackUrl.length == 2) {
            String[] splitParam = splitCallbackUrl[1].split("&");
            if (ArrayUtils.isNotEmpty(splitParam)) {
                for (String param : splitParam) {
                    String[] split = param.split("=");
                    if (split != null && split.length == 2) {
                        String key = split[0];
                        String value = split[1];
                        if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value)) {
                            paramMap.put(key, value);
                        }
                    }
                }
            }
        }

        String callbackResponse = RestUtil.get(callbackUri, paramMap, String.class);
        log.info("request={} callbackUri={} callbackParam={} callbackResponse={}", request, callbackUri, JsonUtil.toJson(paramMap), callbackResponse);
    }

}
